import {Directive} from 'vue';

// 定义 ClickOutside 指令类型
export const clickOutside: Directive<HTMLElement, () => void> = {
  // 当指令绑定到元素并插入到 DOM 中时调用
  mounted(el: any, binding) {
    // 定义点击事件处理函数
    const clickHandler = (event: MouseEvent) => {
      // 判断点击的目标元素是否不在绑定指令的元素内部
      if (!el.contains(event.target as Node)) {
        // 调用绑定指令时传入的回调函数
        binding.value();
      }
    };

    // 定义键盘事件处理函数
    const keyHandler = (event: KeyboardEvent) => {
      // 判断是否按下了 ESC 键
      if (event.key === 'Escape') {
        // 调用绑定指令时传入的回调函数
        binding.value();
      }
    };

    // 给 document 添加 click 事件监听器
    document.addEventListener('click', clickHandler);
    // 给 document 添加 keydown 事件监听器
    document.addEventListener('keydown', keyHandler);

    // 将事件处理函数存储在元素的自定义属性上，方便后续移除监听器
    el.__clickOutsideHandler = clickHandler;
    el.__keyOutsideHandler = keyHandler;
  },
  // 当指令所绑定的元素从 DOM 中移除时调用
  unmounted(el: any) {
    // 移除之前添加到 document 上的 click 事件监听器
    document.removeEventListener('click', el.__clickOutsideHandler);
    // 移除之前添加到 document 上的 keydown 事件监听器
    document.removeEventListener('keydown', el.__keyOutsideHandler);
    // 删除元素上存储的事件处理函数属性
    delete el.__clickOutsideHandler;
    delete el.__keyOutsideHandler;
  },
};
